/**
 * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springblade.modules.bank.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import javax.validation.Valid;

import org.springblade.common.tool.MyStringUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.bank.Wrapper.TmCustomerCallRecordWrapper;
import org.springblade.modules.bank.entity.TmCustomer;
import org.springblade.modules.bank.entity.TmVisitTask;
import org.springblade.modules.bank.entity.TmVisitTaskCustomer;
import org.springblade.modules.bank.service.*;
import org.springblade.modules.bank.util.AESUtil;
import org.springblade.modules.bank.vo.CallRecordWjVO;
import org.springblade.modules.system.entity.Dept;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IDeptService;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.wrapper.UserWrapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.bank.entity.TmCustomerCallRecord;
import org.springblade.modules.bank.vo.TmCustomerCallRecordVO;
import org.springblade.core.boot.ctrl.BladeController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.Duration;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 客户呼叫记录 控制器
 *
 * @author Blade
 * @since 2022-07-08
 */
@RestController
@AllArgsConstructor
@RequestMapping("/tmcustomercallrecord")
@Api(value = "客户呼叫记录", tags = "客户呼叫记录接口")
public class TmCustomerCallRecordController extends BladeController {

	private ITmCustomerCallRecordService tmCustomerCallRecordService;

	private ITmVisitTaskCustomerService iTmVisitTaskCustomerService;

	private ITmCustomerService tmCustomerService;

	private ITmSelectSqlService tmSelectSqlService;

	private IUserService userService;

	private ITmVisitTaskService tmVisitTaskService;

	private IDeptService deptService;

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入tmCustomerCallRecord")
	public R<TmCustomerCallRecord> detail(TmCustomerCallRecord tmCustomerCallRecord) {
		TmCustomerCallRecord detail = tmCustomerCallRecordService.getOne(Condition.getQueryWrapper(tmCustomerCallRecord));
		return R.data(detail);
	}

	/**
	 * 详情
	 */
	@GetMapping("/getRecordNoFile")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入tmCustomerCallRecord")
	public R<TmCustomerCallRecord> getRecordNoFile(TmCustomerCallRecord tmCustomerCallRecord) {
		BladeUser bladeUser = SecureUtil.getUser();
		User user = userService.getById(bladeUser.getUserId());
		LambdaQueryWrapper<TmCustomerCallRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(TmCustomerCallRecord::getCustMgr,user.getCode());
		lambdaQueryWrapper.isNotNull(TmCustomerCallRecord::getCommunicateEndtime);
		lambdaQueryWrapper.isNull(TmCustomerCallRecord::getUploadTime);
		LocalDate now = LocalDate.now();
		LocalDate yesterday = now.minusDays(1);
		LocalDate tomorrow = now.plusDays(1);
		lambdaQueryWrapper.between(TmCustomerCallRecord::getCallRingtimeEnd, yesterday, tomorrow);
		lambdaQueryWrapper.orderByDesc(TmCustomerCallRecord::getCommunicateEndtime);
		List<TmCustomerCallRecord> list = tmCustomerCallRecordService.list(lambdaQueryWrapper);
		if (list.size()>0){
			return R.data(list.get(0));
		}else{
			return R.data(null);
		}
	}

	/**
	 * 分页 客户呼叫记录
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入tmCustomerCallRecord")
	public R<IPage<TmCustomerCallRecordVO>> list(TmCustomerCallRecordVO tmCustomerCallRecord, Query query) throws Exception {
		tmCustomerCallRecord.setStatus("0");
		if(MyStringUtil.isNotEmpty(tmCustomerCallRecord.getPhoneNumber())){
			tmCustomerCallRecord.setPhoneNumber(AESUtil.encrypt(tmCustomerCallRecord.getPhoneNumber(),BankConstants.KEY));
		}
		String custMgrName = tmCustomerCallRecord.getCustMgrName();
		tmCustomerCallRecord.setCustMgrName(null);
		String queryType = tmCustomerCallRecord.getQueryType();
		tmCustomerCallRecord.setQueryType(null);

		QueryWrapper qw = Condition.getQueryWrapper(tmCustomerCallRecord);
		if (tmCustomerCallRecord.getCallDateBegin()!=null&&tmCustomerCallRecord.getCallDateEnd()!=null){
			qw.between("call_date",tmCustomerCallRecord.getCallDateBegin(),tmCustomerCallRecord.getCallDateEnd());
		}
		qw.orderByDesc("update_time");
		if (MyStringUtil.isNotEmpty(custMgrName)){
			qw.like("cust_mgr_name",custMgrName);
		}
		if ("2".equals(queryType)){
			qw.isNotNull("file_path");
		}
		qw.ne("hangup_status","");
		if(MyStringUtil.isNotEmpty(tmCustomerCallRecord.getCustomerName())){
			String encodeCustomerName = AESUtil.encrypt(tmCustomerCallRecord.getCustomerName(),BankConstants.KEY);
			List<TmCustomer> customerList = tmCustomerService.list(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerName,encodeCustomerName));
			if (customerList.size()>0){
				List<String> custmoerCodeList = customerList.stream().map(item->item.getCustomerCode()).collect(Collectors.toList());
				if (custmoerCodeList.size()==1){
					qw.eq("customer_code",custmoerCodeList.get(0));
				}else{
					qw.in("customer_code",custmoerCodeList);
				}
			}else{
				qw.eq("customer_code","xxxx9999");
			}
		}

		if (tmCustomerCallRecord.getDataPermission()!=null){
			if (tmCustomerCallRecord.getDataPermission()==1){}
			else if(tmCustomerCallRecord.getDataPermission()==2){
				List<Dept> deptList = deptService.list(new LambdaQueryWrapper<Dept>().eq(Dept::getParentId,tmCustomerCallRecord.getQueryParentDeptId()));
				List<Long> deptIdList = deptList.stream().map(item->item.getId()).collect(Collectors.toList());
				if (deptIdList.size()==0){
					return R.data(null);
				}
				qw.in("dept_id",deptIdList);
			}else if(tmCustomerCallRecord.getDataPermission()==3){
				qw.eq("dept_id",tmCustomerCallRecord.getQueryDeptId());
			}
		}
		IPage<TmCustomerCallRecord> pages = tmCustomerCallRecordService.page(Condition.getPage(query), qw);

		IPage<TmCustomerCallRecordVO> pagesVO = TmCustomerCallRecordWrapper.build().pageVO(pages);
		pagesVO.getRecords().forEach(item->{
			TmCustomer tmCustomer = tmCustomerService.getOne(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerCode,item.getCustomerCode()));

			try {
				if (tmCustomer!=null&&MyStringUtil.isNotEmpty(tmCustomer.getCustomerName())){
					item.setCustomerName(AESUtil.decrypt(tmCustomer.getCustomerName(),BankConstants.KEY));
				}

				item.setPhoneNumber(AESUtil.decrypt(item.getPhoneNumber(),BankConstants.KEY));

				if (item.getCommunicateBegintime()!=null&&item.getCommunicateEndtime()!=null){
					long second = Duration.between(item.getCommunicateBegintime(), item.getCommunicateEndtime()).toMillis() / 1000;
					String secondStr = second+"秒";
					if(second>60){
						secondStr = second/60 + "分" + second%60 + "秒";
					}
					item.setCommunicateTime(secondStr);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			TmVisitTask tmVisitTask = tmVisitTaskService.getById(item.getTaskId());
			if (tmVisitTask!=null){
				item.setTaskName(tmVisitTask.getTaskName());
			}
		});
		return R.data(pagesVO);
	}

	/**
	 * 自定义分页 客户呼叫记录
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入tmCustomerCallRecord")
	public R<IPage<TmCustomerCallRecordVO>> page(TmCustomerCallRecordVO tmCustomerCallRecord, Query query) {
		IPage<TmCustomerCallRecordVO> pages = tmCustomerCallRecordService.selectTmCustomerCallRecordPage(Condition.getPage(query), tmCustomerCallRecord);
		return R.data(pages);
	}

	/**
	 * 自定义分页 客户呼叫记录
	 */
	@GetMapping("/callRecordWjList")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入tmCustomerCallRecord")
	public R<List<CallRecordWjVO>> callRecordWjList(TmCustomerCallRecordVO tmCustomerCallRecord) {
		List<CallRecordWjVO> callRecordWjVOList = tmCustomerCallRecordService.callRecordWjList(tmCustomerCallRecord);
		callRecordWjVOList.forEach(item->{
			try {
				item.setPhoneNumber(AESUtil.decrypt(item.getPhoneNumber(),BankConstants.KEY));
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
		return R.data(callRecordWjVOList);
	}


	/**
	 * 新增 客户呼叫记录
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入tmCustomerCallRecord")
	public R save(@Valid @RequestBody TmCustomerCallRecord tmCustomerCallRecord) {
		return R.status(tmCustomerCallRecordService.save(tmCustomerCallRecord));
	}

	/**
	 * 修改 客户呼叫记录
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入tmCustomerCallRecord")
	public R update(@Valid @RequestBody TmCustomerCallRecord tmCustomerCallRecord) {
		return R.status(tmCustomerCallRecordService.updateById(tmCustomerCallRecord));
	}

	/**
	 * 新增或修改 客户呼叫记录
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入tmCustomerCallRecord")
	@Transactional(rollbackFor = Exception.class)
	public synchronized R submit(@Valid @RequestBody TmCustomerCallRecord tmCustomerCallRecord) throws Exception {

//		boolean recordIdNull = tmCustomerCallRecord.getId()==null?true:false;
		//如果HangupStatus为空，则设定为空字符串
		if (MyStringUtil.isEmpty(tmCustomerCallRecord.getHangupStatus())){
			tmCustomerCallRecord.setHangupStatus("");
		}
		if(MyStringUtil.isNotEmpty(tmCustomerCallRecord.getPhoneNumber())&&tmCustomerCallRecord.getPhoneNumber().length()<15){
			tmCustomerCallRecord.setPhoneNumber(AESUtil.encrypt(tmCustomerCallRecord.getPhoneNumber(),BankConstants.KEY));
		}
		if(tmCustomerCallRecord.getId()!=null){
			//因为存在异步更新record记录的情况，因此需要得到数据库已有的数据来补全文件信息
			TmCustomerCallRecord tmCustomerCallRecordTemp = tmCustomerCallRecordService.getById(tmCustomerCallRecord.getId());
			if (tmCustomerCallRecordTemp.getUploadTime()!=null){
				tmCustomerCallRecord.setUploadTime(tmCustomerCallRecordTemp.getUploadTime());
				tmCustomerCallRecord.setFileType(tmCustomerCallRecordTemp.getFileType());
				tmCustomerCallRecord.setFileSize(tmCustomerCallRecordTemp.getFileSize());
				tmCustomerCallRecord.setFilePath(tmCustomerCallRecordTemp.getFilePath());
			}
			//1、页面，点击挂断时，立马点击了提交，记录了挂机状态，2、话机挂断成功后，更新时间的时候将挂机状态清空了
			//加上这个判断赋值后，只要hangupStatus被赋值，则不可能被清空
			if (MyStringUtil.isNotEmpty(tmCustomerCallRecordTemp.getHangupStatus())){
				tmCustomerCallRecord.setHangupStatus(tmCustomerCallRecordTemp.getHangupStatus());
			}
			//防止挂机时间被清空
			if (tmCustomerCallRecordTemp.getCommunicateEndtime()!=null){
				tmCustomerCallRecord.setCommunicateEndtime(tmCustomerCallRecordTemp.getCommunicateEndtime());
			}
			if (tmCustomerCallRecordTemp.getCallRingtimeEnd()!=null){
				tmCustomerCallRecord.setCallRingtimeEnd(tmCustomerCallRecordTemp.getCallRingtimeEnd());
			}
		}
		//记录客户经理名称
		if (MyStringUtil.isEmpty(tmCustomerCallRecord.getCustMgrName())){
			User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getCode, tmCustomerCallRecord.getCustMgr()));
			tmCustomerCallRecord.setCustMgrName(user.getRealName());
		}
		tmCustomerCallRecord.setStatus("0");
		tmCustomerCallRecordService.saveOrUpdate(tmCustomerCallRecord);

		if ("0".equals(tmCustomerCallRecord.getHangupStatus())||"1".equals(tmCustomerCallRecord.getHangupStatus())||"4".equals(tmCustomerCallRecord.getHangupStatus())){
			LambdaQueryWrapper<TmVisitTaskCustomer> lambdaQueryWrapper = new LambdaQueryWrapper<>();
			lambdaQueryWrapper.eq(TmVisitTaskCustomer::getCustMgr,tmCustomerCallRecord.getCustMgr());
			lambdaQueryWrapper.eq(TmVisitTaskCustomer::getCustomerCode,tmCustomerCallRecord.getCustomerCode());
			lambdaQueryWrapper.eq(TmVisitTaskCustomer::getTaskId,tmCustomerCallRecord.getTaskId());
			List<TmVisitTaskCustomer> tmVisitTaskCustomerList = iTmVisitTaskCustomerService.list(lambdaQueryWrapper);
			if (tmVisitTaskCustomerList.size()>0){
				tmVisitTaskCustomerList.forEach(item->{
					item.setCallRecordId(tmCustomerCallRecord.getId());
					iTmVisitTaskCustomerService.saveOrUpdate(item);
				});
			}
		}

		if(MyStringUtil.isNotEmpty(tmCustomerCallRecord.getPhoneNumber())){
			tmCustomerCallRecord.setPhoneNumber(AESUtil.decrypt(tmCustomerCallRecord.getPhoneNumber(),BankConstants.KEY));
		}
		return R.data(tmCustomerCallRecord);
	}


	/**
	 * 删除 客户呼叫记录
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		if(MyStringUtil.isNotEmpty(ids)){
			List<TmCustomerCallRecord> removeList = new ArrayList<>();
			Func.toLongList(ids).forEach(id->{
				TmCustomerCallRecord temp = tmCustomerCallRecordService.getById(id);
				if (temp!=null){
					//标记为删除
					temp.setStatus("-1");
					removeList.add(temp);
				}
			});
			if (removeList.size()>0){
				tmCustomerCallRecordService.deleteRecordFile(removeList);
				tmCustomerCallRecordService.saveOrUpdateBatch(removeList);
				return R.success("删除录音成功");
			}
		}
		return R.fail("删除录音失败");
	}

	/**
	 * 删除 客户呼叫记录
	 */
	@PostMapping("/removeByYear")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R removeByYear(@ApiParam(value = "主键集合", required = true) @RequestParam String year) {
		if(MyStringUtil.isNotEmpty(year)){
			List<TmCustomerCallRecord> removeList = tmCustomerCallRecordService.list(new QueryWrapper<TmCustomerCallRecord>().apply("year(call_date)="+year));
			if (removeList.size()>0){
				removeList.forEach(item->{
					//标记为删除
					item.setStatus("-1");
				});

				tmCustomerCallRecordService.deleteRecordFile(removeList);
				tmCustomerCallRecordService.saveOrUpdateBatch(removeList);
				return R.success("删除录音成功");
			}
		}
		return R.fail("删除录音失败");
	}

	/**
	 * 文件上传具体实现方法;
	 *
	 * @param file
	 * @return
	 */
	@RequestMapping("/upload")
	@ResponseBody
	public String handleFileUpload(@RequestParam("file") MultipartFile file) {
		if (!file.isEmpty()) {
			try {
				/*
				 * 这段代码执行完毕之后，图片上传到了工程的跟路径； 大家自己扩散下思维，如果我们想把图片上传到
				 * d:/files大家是否能实现呢？ 等等;
				 * 这里只是简单一个例子,请自行参考，融入到实际中可能需要大家自己做一些思考，比如： 1、文件路径； 2、文件名；
				 * 3、文件格式; 4、文件大小的限制;
				 */
				BufferedOutputStream out = new BufferedOutputStream(
					new FileOutputStream(new File(
						file.getOriginalFilename())));
				System.out.println(file.getName());
				out.write(file.getBytes());
				out.flush();
				out.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				JSONObject retJSON = new JSONObject();
				retJSON.put("msg","ok");
				retJSON.put("code",200);
				return retJSON.toJSONString();
			} catch (IOException e) {
				e.printStackTrace();
				JSONObject retJSON = new JSONObject();
				retJSON.put("msg","ok");
				retJSON.put("code",200);
				return retJSON.toJSONString();
			}

			JSONObject retJSON = new JSONObject();
			retJSON.put("msg","ok");
			retJSON.put("code",200);
			return retJSON.toJSONString();

		} else {
			JSONObject retJSON = new JSONObject();
			retJSON.put("msg","ok");
			retJSON.put("code",200);
			return retJSON.toJSONString();
		}
	}

	/**
	 * 详情
	 */
	@GetMapping("/getFileInfo")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入tmCustomerCallRecord")
	public R<List<JSONObject>> getFileInfo() {
		return R.data(tmSelectSqlService.executeSQL("select x.* from (SELECT YEAR(t.call_date) call_year,ROUND(SUM(t.file_size)/1024/1024,2) file_size from tm_customer_call_record t where t.status=0 group by YEAR(t.call_date)) x order by x.call_year desc"));
	}
}
